<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>绘制立方体</title>
</head>

<body>
    <canvas width="600" height="500" id="oCanvas"></canvas>
    <script src="./cuon-matrix.js"></script>
    <script type="notjs" id="vertex">
        attribute vec3 a_position;
        attribute vec4 a_color;
        varying vec4 v_color;
        uniform mat4 u_Matrix;
        void main () {
            gl_Position =  u_Matrix * vec4(a_position, 1);
            v_color = a_color;
        }
    </script>
    <script type="notjs" id="fragment">
        precision mediump float;
        varying vec4 v_color;
        void main () {
            gl_FragColor = v_color;
        }
    </script>
    <script>
        var oCanvas = document.getElementById('oCanvas');
        var gl = oCanvas.getContext('webgl');
        if (!gl) {
            alert('浏览器不支持webgl');
        }

        // var str = ""
        // 创建着色器函数
        function createShader(gl, type, source) {
            var shader = gl.createShader(type);
            gl.shaderSource(shader, source);
            gl.compileShader(shader);
            var success = gl.getShaderParameter(shader, gl.COMPILE_STATUS);
            if (success) {
                return shader;
            }
            console.log(gl.getShaderInfoLog(shader));
        }

        var vetexStr = document.getElementById('vertex').innerText;
        var fragmentStr = document.getElementById('fragment').innerText;
        var vertexShader = createShader(gl, gl.VERTEX_SHADER, vetexStr);
        var fragmentShader = createShader(gl, gl.FRAGMENT_SHADER, fragmentStr);

        function createProgram(gl, vertexShader, fragmentShader) {
            var program = gl.createProgram();
            gl.attachShader(program, vertexShader);
            gl.attachShader(program, fragmentShader);
            gl.linkProgram(program);
            var success = gl.getProgramParameter(program, gl.LINK_STATUS);
            if (success) {
                return program;
            }
            console.log(gl.getProgramInfoLog(shader));
        }
        var program = createProgram(gl, vertexShader, fragmentShader);
        console.log(program);
        gl.useProgram(program);


        var a_position = gl.getAttribLocation(program, "a_position");
        var pointsize = gl.getAttribLocation(program, "pointsize");
        var a_color = gl.getAttribLocation(program, "a_color");
        var u_Matrix = gl.getUniformLocation(program, "u_Matrix");
        var positionBuffer = gl.createBuffer();
        gl.bindBuffer(gl.ARRAY_BUFFER, positionBuffer);
        var indexBuffer = gl.createBuffer();
        gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, indexBuffer);
        function rotate(deg) {
            var matrix = new Matrix4();
            matrix = matrix.setRotate(deg, 1, 1, 0);
            var viewMatrix = new Matrix4();
            var aspect = oCanvas.width / oCanvas.height;
            viewMatrix.ortho(-3, 3, -3, 3, -100, 100);
            matrix = viewMatrix.multiply(matrix);
            gl.uniformMatrix4fv(u_Matrix, false, matrix.elements);
            draw();
        }
        var deg = 0;
        setInterval(function () {
            deg += 1;
            rotate(deg);
        }, 50);
        gl.enable(gl.CULL_FACE);
        function draw() {
            // 绑定缓冲区数据  
            // 第一个参数绑定的缓冲区  
            //  第二个参数 传入的数据（要求时强类型语言需要你用类型化数组转换一下） 
            // 第三个参数是绘制的方式一般为gl.STATIC_DRAW 表示不会频繁改变缓冲区中的数据（webgl会根据这个参数做一些优化处理）
            gl.bufferData(gl.ARRAY_BUFFER, new Float32Array([
                // 前面  红
                -0.5, -0.5, -0.5, 1, 0, 0,
                0.5, -0.5, -0.5, 1, 0, 0,
                0.5, 0.5, -0.5, 1, 0, 0,
                -0.5, 0.5, -0.5, 1, 0, 0,

                // 后面 绿色
                -0.5, -0.5, 0.5, 0, 1, 0,
                -0.5, 0.5, 0.5, 0, 1, 0,
                0.5, 0.5, 0.5, 0, 1, 0,
                0.5, -0.5, 0.5, 0, 1, 0,

                // 左边 蓝色
               
                -0.5, -0.5, 0.5, 0, 0, 1,
                -0.5, -0.5, -0.5, 0, 0, 1,
                -0.5, 0.5, -0.5, 0, 0, 1,
                -0.5, 0.5, 0.5, 0, 0, 1,

                // 右边 
                0.5, 0.5, -0.5, 0, 1, 1,
               0.5, -0.5, -0.5, 0, 1, 1,
                0.5, -0.5, 0.5, 0, 1, 1,
                
                0.5, 0.5, 0.5, 0, 1, 1,

                // 上面  
                -0.5, 0.5, -0.5, 1, 1, 0,
                0.5, 0.5, -0.5, 1, 1, 0,
                0.5, 0.5, 0.5, 1, 1, 0,
                -0.5, 0.5, 0.5, 1, 1, 0,

                // 下面
                -0.5, -0.5, -0.5, 0, 0, 0,
                 -0.5, -0.5, 0.5, 0, 0, 0,
                0.5, -0.5, 0.5, 0, 0, 0,
                0.5, -0.5, -0.5, 0, 0, 0,

            ]), gl.STATIC_DRAW);
            
            gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, new Uint16Array([
                // 前面
                0, 1, 2,
                2, 3, 0,
                // 后面
                4, 5, 6,
                6, 7, 4,
                // 左边
                8, 9, 10,
                10, 11, 8,
                // 右边
                12, 13, 14,
                14, 15, 12,
                // 上面
                16, 17, 18,
                18, 19, 16,
                // 下面
                20, 21, 22,
                22, 23, 20,
                
            ]), gl.STATIC_DRAW);
            // 为变量分配数据  
            // 第一个参数是为哪个变量分配数据
            // 第二个参数是这个变量拥有数据的分量个数
            // 第三个参数是数据类型
            // 第四个参数是 如果是非浮点型数据是否将数据进行归一化  如果设置为true 数值类型字节大小在-128到127之间的数（BYTE）回转传承-1.0 到1.0之间，数值类型字节大小在0 到255之间的数（UNSIGNED_BYTE）变为0.0 到1.0之间，SHORT也是转换到-1.0 - 1.0之间，如果该值为false  则按照用户输入的数据处理。
            // 第四个参数说白了就是只有在第三个参数除了为FLOAT之外的（即为UNSIGNED_BYTE, SHORT, UNSIGNED_SHORT, INT, UNSIGNED_INT）时实用  
            // 第五个参数为两个顶点之间的字节数，也就是每个顶点的字节数，如果设置为0 则代表两个顶点之间字节数为 顶点数据分量 * 每个元素的字节数
            // 第六个参数为当前变量数据是从每个顶点数据的哪一位开始取
            gl.vertexAttribPointer(a_position, 3, gl.FLOAT, false, 4 * 6, 0);
            gl.vertexAttribPointer(a_color, 3, gl.FLOAT, false, 4 * 6, 4 * 3);
            // 启用这个位置数据
            gl.enableVertexAttribArray(a_position);
            gl.enableVertexAttribArray(a_color);
            // 绘制三角形
            gl.drawElements(gl.TRIANGLES, 36, gl.UNSIGNED_SHORT, 0);
            // gl.drawArrays(gl.TRIANGLES, 0, 6);
        }


        


    </script>
</body>

</html>
